#include "precompiled.h"
#include "holypriest.h"
using namespace std;
using namespace weo::engine::item;
using namespace weo::engine::character::priest;

Holy::Holy()
{
    Healer::Init();
    m_Classnr = weo::engine::character::Character::isAllowed("Priest");
    m_Basevalues.push_back(Attribute("Agility",43));
    m_Basevalues.push_back(Attribute("Intellect",143));
    m_Basevalues.push_back(Attribute("Strength",38));
    m_Basevalues.push_back(Attribute("Stamina",59));
    m_Basevalues.push_back(Attribute("Spirit",163));
    m_Basevalues.push_back(Attribute("CritSpellRating",1.2f*CritSpellRating));
    m_Basevalues.push_back(Attribute("Health",2821)); // health
    m_Basevalues.push_back(Attribute("Mana",2340)); // mana
    m_Equip.Mode(0);
    BOOST_FOREACH(Attribute attr, m_Basevalues)
    {
        handleAttribute(attr);
    }
    // base settings finished
}
float Holy::evaluateTF()
{
    float runtime = 600;
    float time = runtime;
    float GH2 = 57.0f / 70.0f;
    float GH2cost = 455;
    float GH2heal = 1219;
    float spellcrit = m_Equip[12] / CritSpellRating;
    float haste = m_Equip[13] / HasteSpellRating;
    float spelltime = 2.5f/(1+haste/100.0f);
    float manaregooc = m_Equip[21] + 5 * 0.00932715221261f * std::sqrt(m_Equip[2]) * m_Equip[5];
    float manaregic = m_Equip[21] + 5 * 0.00932715221261f * std::sqrt(m_Equip[2]) * 0.3f * m_Equip[5];
    float GH2mana = GH2cost * 0.85f * 0.94f - (manaregic/5) * spelltime;
    float count = floor(m_Equip[35] / GH2mana);
    float castuseratio = ((manaregooc/5)*spelltime) / GH2mana;
    time -= count * spelltime + max<float>(5 * castuseratio, 5);
    time = max<float>(time, 0);
    float regtime = 0;
    float finalFactor = 1.1f;
    if(m_Equip.hasSpecial(979608))
    {
        finalFactor*=1.05f;
    }
    if (time > 0)
    {
        regtime = time / (castuseratio + 1);
        regtime = min<float>(regtime, 0.3f * runtime);
        time -= regtime;
    }
    count += floor(((regtime / 5.0f) * manaregooc) / GH2mana);
    count = min<float>(count, (runtime-regtime) /spelltime);
    float HealGH2 = count * finalFactor * (GH2heal + m_Equip[20] * GH2 * (6.0f / 7.0f + 0.2f)); // no spellcrit here
    return m_CondFactor*HealGH2 / runtime;
}
void Holy::filterEquip(std::vector<std::vector<const weo::engine::item::Item*>>& items)
{
    for(unsigned int i = 0;i<10;i++)
    {
        int subtype = 3;
        if(i == 1 || i == 3)
        {
            vector<const Item*> temp = m_Database->getPtrbyType(1,i+1);
            items.push_back(temp);
        }
        else
        {
            vector<const Item*> temp = m_Database->getPtrbyType(1,i+1,1); // cloth		
            items.push_back(temp);
        }
    }
    items.push_back(m_Database->getPtrbyType(2,0));
    items.push_back(m_Database->getPtrbyType(2,0));
    items.push_back(m_Database->getPtrbyType(3,0));
    items.push_back(m_Database->getPtrbyType(3,0));
    // main hand weapons
    vector<const Item*> mainhand;
    for(int j = 1;j<3;j++)
    {
        vector<const Item*> weapon = m_Database->getPtrbyType(4,j,2);
        vector<const Item*>::iterator it;
        for(it=weapon.begin();it!=weapon.end();it++)
        {
            mainhand.push_back(*it);
        }
    }
    for(int j = 1;j<3;j++)
    {
        vector<const Item*> weapon = m_Database->getPtrbyType(4,j,5);
        vector<const Item*>::iterator it;
        for(it=weapon.begin();it!=weapon.end();it++)
        {
            mainhand.push_back(*it);
        }
    }
    // staff
    vector<const Item*> staff = m_Database->getPtrbyType(4,4,6);
    vector<const Item*>::iterator it;
    for(it=staff.begin();it!=staff.end();it++)
    {
        mainhand.push_back(*it);
    }
    // off hand weapons
    vector<const Item*> offhand = m_Database->getPtrbyType(1,12);
    items.push_back(mainhand);
    items.push_back(offhand);
    items.push_back(m_Database->getPtrbyType(4,5,13)); // wands
    items.push_back(m_Database->getPtrbyType(5,0));
    Healer::filterEquip(items);
}
void Holy::handleAttribute(const Attribute& attr)
{
    switch(attr.Type())
    {
    case 5:
        m_Equip[12] += (m_HasBok ? 1.1f : 1.0f) * attr.Value() * 1.05f * 0.25f;
        Healer::handleAttribute(Attribute(attr.Type(),attr.Value()*1.05f));
        break;
    default:
        Healer::handleAttribute(attr);
        break;
    }
}
